﻿using System;
using System.Collections;
using System.Globalization;
using System.Reflection;
using System.Windows;
using System.Windows.Markup;

namespace AppDesigner.XamlDom
{
    public class CollectionSupport
    {
        /// <summary>
        /// 判断当前类型是否为集合类型
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static bool IsCollectionType(Type type)
        {
            return typeof(IList).IsAssignableFrom(type) 
                || type.IsArray 
                || typeof(IAddChild).IsAssignableFrom(type) 
                || typeof(ResourceDictionary).IsAssignableFrom(type);
        }

        /// <summary>
        /// insert
        /// </summary>
        /// <param name="collectionType"></param>
        /// <param name="collectionInstance"></param>
        /// <param name="newElement"></param>
        /// <param name="index"></param>
        public static void Insert(Type collectionType, object collectionInstance, XamlPropertyValue newElement, int index)
        {
            collectionType.InvokeMember("Insert", BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod, null, collectionInstance, new object[] { index, newElement.GetValueFor(null) }, CultureInfo.InvariantCulture);
        }

        /// <summary>
        /// Adds a value to the end of collectoin
        /// </summary>
        /// <param name="collectionType"></param>
        /// <param name="collectionInstance"></param>
        /// <param name="newElement"></param>
        public static void AddToCollection(Type collectionType, object collectionInstance, XamlPropertyValue newElement)
        {
            IAddChild addChild = collectionInstance as IAddChild;
            if (addChild != null)
            {
                if (newElement is XamlTextValue)
                {
                    addChild.AddText((string)newElement.GetValueFor(null));
                }
                else
                {
                    addChild.AddChild(newElement.GetValueFor(null));
                }
            }
            else if (collectionInstance is ResourceDictionary)
            {
                object val = newElement.GetValueFor(null);
                object key = newElement is XamlObject ? ((XamlObject)newElement).GetXamlAttribute("key") : null;
                if (key == null)
                {
                    if (val is Style)
                    {
                        key = ((Style)val).TargetType;
                    }
                    ((ResourceDictionary)collectionInstance).Add(key, val);
                }
                ((ResourceDictionary)collectionInstance).Add(key, val);
            }
            else
            {
                collectionType.InvokeMember("Add", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Instance, null, collectionInstance, new object[] { newElement.GetValueFor(null) });
            }
        }
    }
}
